<template>
  <div class="app-container launch">
    <el-row :gutter="20">
      <el-col :span="6">
        <el-card
          v-for="(item, index) in options"
          :key="index"
          shadow="never"
          class="table-container"
        >
          <p>{{ item.label }}<i-ep-setting size="4" ml-1 /></p>
          <div class="menu_btn" v-for="vo in item.flow" :key="vo.id">
            <el-link
              href="javascript:;"
              :underline="false"
              @click="
                openDrawer(
                  vo.title + '申请',
                  vo.id,
                  vo.form_data,
                  vo.rules,
                  vo.process,
                  vo.field
                )
              "
            >
              <el-avatar
                shape="square"
                :icon="vo.icon"
                :class="vo.class_name"
              />
              <span>{{ vo.title }}</span>
            </el-link>
          </div>
        </el-card>
      </el-col>
      <el-col :span="18">
        <el-card shadow="never" class="table-container">
          <el-tabs v-model="activeName" @tab-click="handleClick">
            <el-tab-pane label="全部" name="all" />
            <el-tab-pane label="待审批" name="pending" />
            <el-tab-pane label="审核通过" name="success" />
            <el-tab-pane label="审批拒绝" name="rejected" />
          </el-tabs>
          <el-table v-loading="loading" :data="pageData" style="width: 100%">
            <el-table-column prop="nickname" label="申请人" />
            <el-table-column prop="created_at" label="申请时间" />
            <el-table-column label="类型">
              <template #default="scope">
                <span v-if="scope.row.type_name">{{
                  scope.row.flow_name + "-" + scope.row.type_name
                }}</span>
                <span v-else>{{ scope.row.flow_name }}</span>
              </template>
            </el-table-column>
            <el-table-column prop="org_name" label="所属部门" />
            <el-table-column prop="approved_by" label="当前审批人" />
            <el-table-column prop="status_d" label="审批状态">
              <template #default="scope">
                <el-tag
                  :key="scope.row.id"
                  :type="scope.row.status_color"
                  effect="plain"
                >
                  {{ scope.row.status_d }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column label="操作">
              <template #default="scope">
                <el-button
                  v-if="scope.row.status == 0"
                  v-hasPerm="['approval@revoke']"
                  type="warning"
                  circle
                  title="撤回"
                  @click="handleRevoke(scope.row.id)"
                  ><i-ep-RefreshLeft
                /></el-button>
                <el-button
                  type="success"
                  circle
                  title="查看"
                  @click="handleView(scope.row.id)"
                  ><i-ep-Promotion
                /></el-button>
                <el-button
                  v-if="scope.row.status == -1 || scope.row.status == 2"
                  v-hasPerm="['approval@del']"
                  circle
                  type="danger"
                  title="删除"
                  @click="handleDelete(scope.row.id)"
                  ><i-ep-delete
                /></el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-card>
      </el-col>
    </el-row>
    <el-drawer
      v-model="drawer"
      :title="drawerTitle"
      direction="rtl"
      size="65%"
      :before-close="handleClose"
    >
      <el-form
        ref="userFormRef"
        label-position="right"
        label-width="auto"
        :rules="rules"
        :model="formData"
      >
        <el-form-item
          v-for="row in form_data"
          :key="row.field"
          :label="row.label"
          :prop="row.field"
        >
          <el-select
            v-if="row.type === 'select'"
            :placeholder="'请选择' + row.label"
            style="width: 300px"
            v-model="formData[row.field]"
          >
            <el-option
              v-for="item in row.options"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
          <el-radio-group
            v-model="formData[row.field]"
            v-if="row.type === 'radio'"
          >
            <el-radio
              :value="item.value"
              border
              v-for="item in row.options"
              :key="item.value"
              >{{ item.label }}</el-radio
            >
          </el-radio-group>
          <el-input
            v-if="row.type === 'input'"
            :placeholder="'请输入' + row.label"
            v-model="formData[row.field]"
            style="width: 300px"
          />
          <el-input
            v-if="row.type === 'textarea'"
            :placeholder="'请输入' + row.label"
            type="textarea"
            v-model="formData[row.field]"
          />
          <el-date-picker
            v-if="row.type === 'datetime'"
            type="datetime"
            :placeholder="'请输入' + row.label"
            format="YYYY-MM-DD HH:mm:ss"
            date-format="MM-DD, YYYY"
            time-format="HH:mm"
            value-format="YYYY-MM-DD HH:mm:ss"
            v-model="formData[row.field]"
          />
          <el-upload
            v-if="row.type === 'file'"
            v-model:file-list="formData[row.field]"
            class="upload-demo"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload"
            :data="{ field: row.field }"
            :action="uploadUrl"
            :headers="headers"
          >
            <el-button type="primary">上传附件</el-button>
            <template #tip>
              <div class="el-upload__tip">文件大小不超过 2MB!</div>
            </template>
          </el-upload>
        </el-form-item>
      </el-form>
      <div style="padding-left: 30px; padding-top: 15px; margin-bottom: 5px">
        <h3>审批流程</h3>
        <el-timeline v-if="process.length > 0">
          <el-timeline-item
            v-for="(activity, index) in process"
            :key="index"
            :icon="activity.icon"
            :type="activity.type"
            :color="activity.color"
            :size="activity.size"
            :timestamp="activity.timestamp"
          >
            <div
              class="timeline-content"
              v-for="item in activity.content"
              :key="item.id"
            >
              <el-avatar
                fit="cover"
                shape="square"
                :size="32"
                :src="item.avatar"
              />
              <div class="timeline-title">{{ item.nickname }}</div>
            </div>
          </el-timeline-item>
        </el-timeline>
        <el-result
          v-if="process.length == 0"
          icon="info"
          title="置审批流程"
          sub-title="请联系管理员设置审批流程"
        >
          <template #extra>
            <el-link href="#/flow/index">
              <el-button type="primary" plain>设置</el-button>
            </el-link>
          </template>
        </el-result>
      </div>
      <template #footer>
        <div style="flex: auto">
          <el-button @click="drawer = false">取消</el-button>
          <el-button type="primary" @click="handleSubmit">确认</el-button>
        </div>
      </template>
    </el-drawer>

    <el-drawer v-model="viewDrawer" title="事项审批" direction="rtl" size="65%">
      <el-descriptions class="margin-top" title="审批" :column="3" border>
        <el-descriptions-item>
          <template #label>
            <div class="cell-item">
              <el-icon :style="iconStyle">
                <CollectionTag />
              </el-icon>
              事项名称
            </div>
          </template>
          {{ approvalData.title }}
        </el-descriptions-item>
        <el-descriptions-item>
          <template #label>
            <div class="cell-item">
              <el-icon :style="iconStyle">
                <OfficeBuilding />
              </el-icon>
              所属部门
            </div>
          </template>
          {{ approvalData.org_name }}
        </el-descriptions-item>
        <el-descriptions-item>
          <template #label>
            <div class="cell-item">
              <el-icon :style="iconStyle">
                <Menu />
              </el-icon>
              类型
            </div>
          </template>
          <span v-if="approvalData.type_name">{{
            approvalData.flow_name + "-" + approvalData.type_name
          }}</span>
          <span v-else>{{ approvalData.flow_name }}</span>
        </el-descriptions-item>
        <el-descriptions-item>
          <template #label>
            <div class="cell-item">
              <el-icon :style="iconStyle">
                <Clock />
              </el-icon>
              时间
            </div>
          </template>
          {{ approvalData.start_time + " ~ " + approvalData.end_time }}
        </el-descriptions-item>
        <el-descriptions-item v-if="approvalData.address">
          <template #label>
            <div class="cell-item">
              <el-icon :style="iconStyle">
                <Location />
              </el-icon>
              地点
            </div>
          </template>
          {{ approvalData.address }}
        </el-descriptions-item>
        <el-descriptions-item>
          <template #label>
            <div class="cell-item">
              <el-icon :style="iconStyle">
                <Flag />
              </el-icon>
              当前审批人
            </div>
          </template>
          {{ approvalData.approved_by }}
        </el-descriptions-item>
        <el-descriptions-item>
          <template #label>
            <div class="cell-item">
              <el-icon :style="iconStyle">
                <Compass />
              </el-icon>
              审批状态
            </div>
          </template>
          <el-tag>{{ approvalData.status_d }}</el-tag>
        </el-descriptions-item>
        <el-descriptions-item span="3">
          <template #label>
            <div class="cell-item">
              <el-icon :style="iconStyle">
                <Tickets />
              </el-icon>
              原由
            </div>
          </template>
          {{ approvalData.reason }}
        </el-descriptions-item>
        <el-descriptions-item
          v-for="(item, index) in approvalData.extra"
          :key="index"
        >
          <template #label>
            <div class="cell-item">
              <el-icon :style="iconStyle">
                <Tickets />
              </el-icon>
              {{ item.label }}
            </div>
          </template>
          {{ item.value }}
        </el-descriptions-item>
      </el-descriptions>
      <div ml-5 mt-5>
        <h3>审批流程</h3>
        <el-timeline>
          <el-timeline-item
            v-for="(activity, index) in process"
            :key="index"
            :icon="activity.icon"
            :type="activity.type"
            :color="activity.color"
            :size="activity.size"
            :timestamp="activity.timestamp"
          >
            <div
              class="timeline-content"
              v-for="item in activity.content"
              :key="item.id"
            >
              <el-avatar
                fit="cover"
                shape="square"
                :size="32"
                :src="item.avatar"
              />
              <el-icon
                v-if="item.status == 1"
                class="timeline-icon"
                color="#67C23A"
                ><CircleCheckFilled
              /></el-icon>
              <el-icon
                v-if="item.status == 2"
                class="timeline-icon"
                color="#F56C6C"
                ><CircleCloseFilled
              /></el-icon>
              <div class="timeline-title">{{ item.nickname }}</div>
            </div>
          </el-timeline-item>
        </el-timeline>
      </div>
      <template #footer>
        <div style="flex: auto">
          <el-button @click="viewDrawer = false">关闭</el-button>
        </div>
      </template>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
defineOptions({
  name: "OfficeLaunch",
  inheritAttrs: false,
});
import {
  getOptions,
  addApproval,
  getApprovalPage,
  deleteApproval,
  revokeApproval,
  getApprovalForm,
} from "@/api/approval";
import {
  ApprovalOptions,
  ApprovalForm,
  ApprovalPage,
  ApprovalQuery,
} from "@/api/approval/types";
import type { UploadProps, UploadUserFile } from "element-plus";
const options = ref<ApprovalOptions[]>();
const form_data = ref<any>();
const rules = ref<any>();
const fields = ref<any>();
const process = ref<any>();
const activeName = ref("all");
const userFormRef = ref(ElForm); // 表单
const loading = ref(false); //  加载状态
const drawer = ref(false);
const viewDrawer = ref(false);
const iconStyle = computed(() => {
  const marginMap = {
    large: "8px",
    default: "6px",
    small: "4px",
  };
  return {
    marginRight: marginMap.default,
  };
});
const drawerTitle = ref("");
const queryFormRef = ref(ElForm); // 查询表单
const approvalData = reactive<ApprovalPage>({});
const queryParams = reactive<ApprovalQuery>({
  p: 1,
  limit: 10,
});
const total = ref(0); // 数据总数
const pageData = ref<ApprovalPage[]>(); // 分页数据
// 表单数据
const formData = reactive<ApprovalForm>({});

const uploadUrl = ref(
  import.meta.env.VITE_APP_API_URL + "/admin/approval/upload"
);
const headers = ref({
  Authorization: localStorage.getItem("accessToken"),
});

const handleAvatarSuccess: UploadProps["onSuccess"] = (
  response,
  uploadFile
) => {
  formData[response.data.field] = response.data.url;
};
//const imageType = ["image/jpeg", "image/png", "image/jpg"];

const beforeAvatarUpload: UploadProps["beforeUpload"] = (rawFile) => {
  // if (!imageType.includes(rawFile.type)) {
  //   ElMessage.error("图片格式不正确");
  //   return false;
  // } else
  if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error("文件大小不超过 2MB!");
    return false;
  }
  return true;
};

const handleClick = (tab: any, event: any) => {
  queryParams.status = tab.props.name;
  handleQuery(queryParams);
};

function openDrawer(
  title: string,
  id: any,
  data: any,
  rule?: any,
  processes?: any,
  field?: any
) {
  process.value = [];
  drawer.value = true;
  drawerTitle.value = title;
  form_data.value = data;
  rules.value = rule;
  process.value = processes;
  fields.value = field;
  formData.flow_id = id;
}

const handleClose = (done: () => void) => {
  if (hasMethod(userFormRef.value, "clearValidate")) {
    userFormRef.value.resetFields();
    userFormRef.value.clearValidate();
  }
  drawer.value = false;
};

function hasMethod(
  obj: any,
  methodName: string
): obj is { [key: string]: (...args: any[]) => any } {
  return typeof obj[methodName] === "function";
}

function handleView(ids: any) {
  viewDrawer.value = true;
  getApprovalForm(ids)
    .then(({ data }) => {
      Object.assign(approvalData, { ...data });
      process.value = data.flow;
    })
    .finally(() => ({}));
}

/**
 * 重置表单
 */
function restForm() {
  drawer.value = false;
  if (hasMethod(userFormRef.value, "clearValidate")) {
    userFormRef.value.resetFields();
    userFormRef.value.clearValidate();
  }
  formData.flow_id = undefined;
  handleQuery();
}

/** 表单提交 */
const handleSubmit = useThrottleFn(() => {
  if (process.value.length == 0)
    ElMessage.error("审核流程未设置，请联系管理员");
  userFormRef.value.validate((valid: any) => {
    if (valid) {
      const loading = ElLoading.service({
        lock: true,
        text: "提交中...",
        background: "rgba(0, 0, 0, 0.7)",
      });
      addApproval(formData)
        .then(() => {
          ElMessage.success("发起成功");
          restForm();
          loading.close();
        })
        .finally(() => loading.close());
    } else {
      return false;
    }
  });
}, 3000);

function loadOptions() {
  getOptions().then((response) => {
    options.value = response.data;
  });
}

/** 查询 */
function handleQuery() {
  loading.value = true;
  getApprovalPage(queryParams)
    .then(({ data }) => {
      pageData.value = data.items;
      total.value = data.total;
    })
    .finally(() => {
      loading.value = false;
    });
}

/** 删除 */
function handleDelete(ids?: number) {
  if (!ids) {
    ElMessage.warning("请选择删除项");
    return;
  }
  ElMessageBox.confirm("确认删除?", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(function () {
    deleteApproval({ ids: ids }).then(() => {
      ElMessage.success("删除成功");
      resetQuery();
    });
  });
}

/** 撤回 */
function handleRevoke(id?: number) {
  if (!id) {
    ElMessage.warning("请选择撤回项");
    return;
  }
  ElMessageBox.confirm("确认撤回?", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(function () {
    revokeApproval({ ids: id }).then(() => {
      ElMessage.success("撤回成功");
      resetQuery();
    });
  });
}

/** 重置查询 */
function resetQuery() {
  queryParams.p = 1;
  handleQuery();
}

onMounted(() => {
  loadOptions();
  handleQuery();
});
</script>
<style lang="scss" scoped>
.launch {
  ::v-deep(.el-timeline-item__node--large) {
    height: var(--el-timeline-node-size-large);
    left: -8px !important;
    width: var(--el-timeline-node-size-large);
  }
  .el-timeline-item {
    padding-bottom: 45px;
    position: relative;
  }
  .el-timeline {
    --el-timeline-node-size-normal: 26px;
    --el-timeline-node-size-large: 28px;
    --el-timeline-node-color: var(--el-border-color-light);
  }
  .el-timeline-item__icon {
    font-size: 20px;
  }
  .timeline-content {
    display: inline-block;
    position: relative;
    min-width: 110px;
  }
  .timeline-content .timeline-title {
    position: absolute;
    left: 35%;
    top: 18%;
  }
  .timeline-content .timeline-icon {
    position: absolute;
    left: 23%;
    top: -18%;
    z-index: 1000;
  }
  .box-card {
    text-align: center;
    font-size: 12px;
  }
  .menu_btn {
    display: inline-block;
    font-size: 14px;
    margin-left: 0;
    padding: 12px 55px 12px 12px;
    margin-bottom: 10px;
    border-radius: 5px;
  }

  .table-container {
    margin-bottom: 10px;
  }

  .purple {
    background-color: rgb(179, 127, 235);
  }

  .blue {
    background: #409eff;
  }

  .green {
    background-color: #67c23a;
  }

  .red {
    background-color: #f56c6c;
  }

  .yellow {
    background-color: #e6a23c;
  }

  .menu_btn span {
    margin-left: 8px;
  }

  .menu_btn:hover {
    background-color: #f2f2f2;
  }

  .el-link:hover {
    color: #000000;
  }
}
</style>
